#include "save_as_cell.h"
#include "../../layout/layout.hpp"
#include "../../undoRedo/undoRedo.hpp"
#include "../../utils/kutils.h"

namespace qbe::SaveAsCell {
#define CELL_LAYOUT_TYPE "1"
#define CELL_DEVICE_TYPE "2"

void exit(ecs::Query query, state::AllModeType enter_mode) {}
void init(entt::registry& reg, ecs::Commands commands, ecs::Query query) {}
void update(entt::registry& ecs_reg, ecs::Query query, ecs::Bus& bus, ecs::EventWriter<msg::RenderEvent> event) {
  auto& state = query.get_resource<state::State>();

  // 仅在模式执行
  if (state.getEditingMode() != state::EditingModeType::SaveAsCell)
    return;
  //获取当前操作的Cell
  auto& cmd = query.get_resource<layout::CellCmd>();
  auto current_cell = cmd.get_cell();
  auto& reg = current_cell->reg;
  auto& cell_state = query.get_resource<layout::CellState>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  //获取选择对象
  /*select::SelectModel& selectModel = selectModel_r.get();
  std::vector<entt::entity> selecc_arr = selectModel.getSelectObj();*/
  std::vector<entt::entity> select_arr;
  for (auto [e] : reg.view<select::SelectTag>().each()) {
    select_arr.push_back(e);
  }
  if (select_arr.empty()) {
    state.exit();
    return;
  }

  //获取当前操作的Cell

  auto& param = query.get_resource<SaveAsCellModel>();
  if (param.is_open_ui == false) {
    bus.send(UiMessage::SaveAsCellUi_Open());
    param.is_open_ui = true;
  }
  //界面取消按钮处理
  {
    auto res = bus.receive<UiMessage::SaveAsCellUi_Cancel>();
    if (!res.empty()) {
      bus.send(UiMessage::SaveAsCellUi_Close());
      param.is_open_ui = false;
      state.exit();
    }
  }
  auto res = bus.receive<UiMessage::SaveAsCellUi_Ok>();
  if (!res.empty()) {

    qlib::Library::s_ptr lib = res[0].lib;                          //将要另存为的lib
    auto current_lib = query.get_resource<qlib::Library::s_ptr>();  //当前操作版图lib
    param.is_current_board = false;
    if (current_lib == lib) {
      param.is_current_board = true;
    }
    std::vector<std::any> copy_selected = auxiliary::copyElement(current_cell, select_arr);
    // 获取选中对象包围盒与中心
    auto box = qbe::auxiliary::calBonndingBox(copy_selected);
    auto center = qlib::box_center(box);
    auxiliary::translateGraph(copy_selected, {0 - center.x, 0 - center.y});

    //组织成新cell
    std::shared_ptr<qlib::Cell> new_cell = std::make_shared<qlib::Cell>();
    std::vector<std::shared_ptr<qlib::Cell>> copy_cell;
    std::vector<std::shared_ptr<qlib::Reference>> copy_refs;
    auxiliary::AddGraphToCell(new_cell, copy_selected);
    for (auto ele : copy_selected) {
      const std::type_info& stored_type = ele.type();
      if (stored_type == typeid(qlib::Reference::s_ptr)) {
        qlib::Reference::s_ptr ref = std::any_cast<qlib::Reference::s_ptr>(ele);
        copy_refs.push_back(ref);
      }
    }

    if (param.is_current_board == false)
      copy_cell = auxiliary::deepCopyAllRefs(copy_refs);

    new_cell->name = res[0].name;
    if (res[0].is_layout_cell == false) {
      //qlib::set_gds_property(new_cell->properties, 0, CELL_DEVICE_TYPE);
      new_cell->setCellDisplayType(CELL_DEVICE_TYPE);
    } else {
      //qlib::set_gds_property(new_cell->properties, 0, CELL_LAYOUT_TYPE);
      new_cell->setCellDisplayType(CELL_LAYOUT_TYPE);
    }

    //bool is_library_exist = false;
    std::vector<std::string> name_list;
    for (auto it : lib->cells) {
      name_list.push_back(it->name);
      /*if (new_cell == it) {
        is_library_exist = true;
      }*/
    }
    /*if (is_library_exist == false) */
    {
      std::string new_name = auxiliary::duplicateNameVerify(new_cell->name, name_list);
      new_cell->name = new_name;
    }
    lib->add(new_cell);

    for (auto i : copy_cell) {
      bool is_library_exist = false;
      std::vector<std::string> name_list;
      for (auto it : lib->cells) {
        name_list.push_back(it->name);
        if (i == it) {
          is_library_exist = true;
        }
      }
      if (is_library_exist == false) {
        std::string new_name = auxiliary::duplicateNameVerify(i->name, name_list);
        i->name = new_name;
      }

      lib->add(i);
    }
    bus.send<qbe::UiMessage::UpdateFileLisetFromLibrary>(qbe::UiMessage::UpdateFileLisetFromLibrary{lib});
    // 用单元替换选中对象
    if (res[0].is_replce_select_with_ref == true) {
      if (true == param.is_current_board) {  // 如果另存为当前文件
        current_lib->remove(new_cell);       // 另存为单元生成的单元坐标有变化，删除重新生成单元
      }
      replaceSelectedWithRef(query, param.is_current_board, current_cell, select_arr, res[0]);
    }
    bus.send<qbe::UiMessage::UpdateFileLisetFromLibrary>(qbe::UiMessage::UpdateFileLisetFromLibrary{current_lib});
    //event.send(msg::RenderEvent{msg::RenderCode::CellUpdate});  //确定后版图更新

    // 保存
    bus.send<qbe::UiMessage::updateLibTreeFromMem>(qbe::UiMessage::updateLibTreeFromMem{res[0].mode_name, res[0].pro_name, res[0].lib_name});

    layout_cmd.render_update();  //确定后版图更新
    state.exit();
    if (param.is_open_ui == true) {
      bus.send(UiMessage::SaveAsCellUi_Close());
      param.is_open_ui = false;
    }
  }
}
void post(entt::registry& reg, ecs::Commands commands, ecs::Query query, ecs::Bus& bus) {}

void replaceSelectedWithRef(ecs::Query query, bool is_current_board, qlib::Cell::s_ptr cell, std::vector<entt::entity>& selected_eles,
                            UiMessage::SaveAsCellUi_Ok& param) {
  auto current_lib = query.get_resource<qlib::Library::s_ptr>();

  //复制内核对象
  auto copy_selected = auxiliary::copyElement(cell, selected_eles);
  std::shared_ptr<qlib::Cell> new_cell = std::make_shared<qlib::Cell>();
  new_cell->name = param.name;
  //向cell中加入基本图形
  auxiliary::AddGraphToCell(new_cell, copy_selected);
  if (param.is_layout_cell == false) {
    //qlib::set_gds_property(new_cell->properties, 0, CELL_DEVICE_TYPE);
    new_cell->setCellDisplayType(CELL_DEVICE_TYPE);

  } else {
    //qlib::set_gds_property(new_cell->properties, 0, CELL_LAYOUT_TYPE);
    new_cell->setCellDisplayType(CELL_LAYOUT_TYPE);
  }

  std::vector<std::string> name_list;
  for (auto it : current_lib->cells) {
    name_list.push_back(it->name);
  }

  std::string new_name = auxiliary::duplicateNameVerify(new_cell->name, name_list);
  new_cell->name = new_name;

  // 在当前单元所属文件中新增单元
  current_lib->add(new_cell);

  // 创建一个引用指向新增的单元
  std::shared_ptr<qlib::Reference> ref(new qlib::Reference);
  ref->cell = new_cell;
  //ref->m_instance_name = (QString("U%1").arg(LayoutCtrlData::getInstanceIndex())).toStdString();
  auto entity = cell->reg.create();
  auto& new_ptr = cell->reg.emplace<std::shared_ptr<qlib::Reference>>(entity);
  new_ptr = ref;
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  layout_cmd.add_cell(new_cell);
  layout_cmd.add(entity);
  for (auto i : selected_eles) {
    //cell->reg.destroy(i);
    layout_cmd.remove(i);
  }
}
}  // namespace qbe::SaveAsCell